Let's Go by Alex Edwards
Author:Alex Edwards
Language: eng
Format: epub
Using the helpers
Alright, letâs start putting the Validator type to use!
Weâll head back to our cmd/web/handlers.go file and update it to embed a Validator instance in our snippetCreateForm struct, and then use this to perform the necessary validation checks on the form data.
Tip: If youâre not familiar with the concept of embedding structs in Go, Eli Bendersky has written a good introduction on the topic and I recommend quickly reading it before you continue.
Like so:
File: cmd/web/handlers.go package main import ( "errors" "fmt" "net/http" "strconv" "snippetbox.alexedwards.net/internal/models" "snippetbox.alexedwards.net/internal/validator" // New import "github.com/julienschmidt/httprouter" ) ... // Remove the explicit FieldErrors struct field and instead embed the Validator // type. Embedding this means that our snippetCreateForm "inherits" all the // fields and methods of our Validator type (including the FieldErrors field). type snippetCreateForm struct { Title string Content string Expires int validator.Validator } func (app *application) snippetCreatePost(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { app.clientError(w, http.StatusBadRequest) return } expires, err := strconv.Atoi(r.PostForm.Get("expires")) if err != nil { app.clientError(w, http.StatusBadRequest) return } form := snippetCreateForm{ Title: r.PostForm.Get("title"), Content: r.PostForm.Get("content"), Expires: expires, // Remove the FieldErrors assignment from here. } // Because the Validator type is embedded by the snippetCreateForm struct, // we can call CheckField() directly on it to execute our validation checks. // CheckField() will add the provided key and error message to the // FieldErrors map if the check does not evaluate to true. For example, in // the first line here we "check that the form.Title field is not blank". In // the second, we "check that the form.Title field has a maximum character // length of 100" and so on. form.CheckField(validator.NotBlank(form.Title), "title", "This field cannot be blank") form.CheckField(validator.MaxChars(form.Title, 100), "title", "This field cannot be more than 100 characters long") form.CheckField(validator.NotBlank(form.Content), "content", "This field cannot be blank") form.CheckField(validator.PermittedInt(form.Expires, 1, 7, 365), "expires", "This field must equal 1, 7 or 365") // Use the Valid() method to see if any of the checks failed. If they did, // then re-render the template passing in the form in the same way as // before. if !form.Valid() { data := app.newTemplateData(r) data.Form = form app.render(w, http.StatusUnprocessableEntity, "create.tmpl", data) return } id, err := app.snippets.Insert(form.Title, form.Content, form.Expires) if err != nil { app.serverError(w, err) return } http.Redirect(w, r, fmt.Sprintf("/snippet/view/%d", id), http.StatusSeeOther) }
So this is shaping up really nicely.
Weâve now got an internal/validator package with validation rules and logic that can be reused across our application, and it can easily be extended to include additional rules in the future. Both form data and errors are neatly encapsulated in a single snippetCreateForm struct â which we can easily pass to our templates â and the API for displaying error messages and re-populating the data in our templates is simple and consistent.
If you like, go ahead and re-run the application now. All being well, you should find that the form and validation rules are working correctly and in exactly the same manner as before.
Download
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.
| Ancient, Classical & Medieval | Anthologies |
| British & Irish | Japanese & Haiku |
| Love Poems | Regional & Cultural |
| Themes & Styles | United States |
| Women Authors |
The Universe of Us by Lang Leav(15033)
The Sun and Her Flowers by Rupi Kaur(14474)
Adultolescence by Gabbie Hanna(8889)
Whiskey Words & a Shovel II by r.h. Sin(7981)
Love Her Wild by Atticus(7723)
Smoke & Mirrors by Michael Faudet(6153)
Wiseguy by Nicholas Pileggi(5718)
The Princess Saves Herself in This One by Amanda Lovelace(4937)
Love & Misadventure by Lang Leav(4820)
Memories by Lang Leav(4777)
Milk and Honey by Rupi Kaur(4716)
Bluets by Maggie Nelson(4520)
Too Much and Not the Mood by Durga Chew-Bose(4306)
Pillow Thoughts by Courtney Peppernell(4249)
Good morning to Goodnight by Eleni Kaur(4211)
The Poetry of Pablo Neruda by Pablo Neruda(4070)
Algedonic by r.h. Sin(4042)
HER II by Pierre Alex Jeanty(3585)
Stuff I've Been Feeling Lately by Alicia Cook(3422)